import sys

if __name__ == "__main__":
    variables = ['instanceName', 'instanceType', 'depotNum', 'cusNum']
    is_multi_depot = True
    is_open = False
    is_symmetrical = True
    if sys.argv[2] == 'MDVRP':
        variables.append('vehicleCap')
        variables.append('nodeDemands')
        variables.append('serviceTimes')
        variables.append('tourNum')
        variables.append('duration')
    elif sys.argv[2] == 'MDOVRP':
        variables.append('vehicleCap')
        variables.append('nodeDemands')
        is_open = True
    elif sys.argv[2] == 'LRP':
        variables.append('vehicleCap')
        variables.append('nodeDemands')
        variables.append('vehicleCost')
        variables.append('depotCosts')
    elif sys.argv[2] == 'MDGVRP' or sys.argv[2] == 'GVRP':
        variables.append('fuelStationNum')
        variables.append('serviceTimes')
        variables.append('fuelTime')
        variables.append('speed')
        variables.append('range')
        variables.append('duration')
        if sys.argv[2] == 'GVRP':
            is_multi_depot = False
    else:
        print("unsupported problem type "+sys.argv[2])
        exit(1)
    variables.append('distances')

    function_suffix = '\n'+'\t}\n'

    ini_total_node_num_str = '\tvoid initialTotalNodeNum() {\n\t\ttotalNodeNum = depotNum+cusNum'
    ini_non_cus_num_str = '\tvoid initialNonCusNum() {\n\t\tnonCusNodeNum = depotNum'
    if 'fuelStationNum' in variables:
        ini_total_node_num_str += '+fuelStationNum'
        ini_non_cus_num_str += '+fuelStationNum'
    ini_total_node_num_str += ';' + function_suffix
    ini_non_cus_num_str += ';' + function_suffix

    expressions = ''
    macro_names = []
    constructor_func_str = '\n\tInstance('

    if is_multi_depot:
        macro_names.append('MultiDepots')
    if is_open:
        macro_names.append('OpenRoutes')
    if is_symmetrical:
        macro_names.append('Symmetrical')

    counter = 0
    for var in variables:
        expressions += '\t'
        expression = ''
        cons_expression = ''
        counter += 1
        if var == 'instanceName':
            expression = 'string '
            cons_expression = 'const string& '
        elif var == 'instanceType':
            expression = 'string '
            cons_expression = 'const string& '
        elif var == 'depotNum':
            cons_expression = expression = 'int '
        elif var == 'cusNum':
            cons_expression = expression = 'int '
        elif var == 'distances':
            expression = 'vector<vector<DisType>> '
            cons_expression = 'const vector<vector<DisType>>& '
        elif var == 'fuelStationNum':
            expressions += "// The number of fuel stations is the total number of fuel stations and depots\n\t"
            macro_names.append('FuelStation')
            cons_expression = expression = 'int '
        elif var == 'vehicleCap':
            cons_expression = expression = 'int '
        elif var == 'nodeDemands':
            expression = 'vector<int> '
            cons_expression = 'const vector<int>& '
        elif var == 'serviceTimes':
            macro_names.append('ServiceTime')
            expression = 'vector<int> '
            cons_expression = 'const vector<int>& '
        elif var == 'fuelTime':
            macro_names.append('FuelTime')
            cons_expression = expression = 'int '
        elif var == 'duration':
            cons_expression = expression = 'int '
        elif var == 'tourLength':
            cons_expression = expression = 'int '
        elif var == 'tourNum':
            cons_expression = expression = 'int '
        elif var == 'vehicleCost':
            macro_names.append('VehicleCost')
            cons_expression = expression = 'int '
        elif var == 'depotCosts':
            macro_names.append('DepotCost')
            expression = 'vector<int> '
            cons_expression = 'const vector<int>& '
        elif var == 'speed':
            macro_names.append('Speed')
            cons_expression = expression = 'int '
        elif var == 'range':
            cons_expression = expression = 'double '
        else:
            print("unsupported variables "+var)
            exit(1)
        expression += var
        cons_expression += var
        expressions += expression+';\n'
        constructor_func_str += cons_expression+', '
        if counter % 4 == 0:
            constructor_func_str += '\n\t\t'

    if constructor_func_str[-1] == '\t':
        constructor_func_str = constructor_func_str[:-5]
    else:
        constructor_func_str = constructor_func_str[:-2]
    constructor_func_str += '):\n\t\t\t'
    counter = 0
    for var in variables:
        constructor_func_str += var+'('+var+'), '
        counter += 1
        if counter % 4 == 0:
            constructor_func_str += '\n\t\t\t'
    if constructor_func_str[-1] == '\t':
        constructor_func_str = constructor_func_str[:-6]
    else:
        constructor_func_str = constructor_func_str[:-2]
    constructor_func_str += '{'+'\n\t\t\tinitialTotalNodeNum();\n\t\t\t'+'initialNonCusNum();'+function_suffix

    default_constructor_func = '\n\tInstance() = default;\n'

    macro = '\n'
    for macro_name in macro_names:
        macro += '#define '+macro_name+'\n'

    with open(sys.argv[1]+'/'+"Instance.h", 'w') as f:
        f.write('#ifndef BASICHEADERSOFROUTESRELATEDPROBLEMS_INSTANCE_H\n' +
                '#define BASICHEADERSOFROUTESRELATEDPROBLEMS_INSTANCE_H\n\n' +
                '#include <string>\n#include <vector>\n#include "DisType.h"\nusing namespace std;\n' +
                macro +
                '\nstruct Instance{\n' +
                expressions +
                '\tint nonCusNodeNum;\n' +
                '\tint totalNodeNum;\n\n' +
                ini_total_node_num_str +
                ini_non_cus_num_str +
                constructor_func_str +
                default_constructor_func +
                '};\n#endif')
